package com.geek.novel.ui

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Typeface
import android.os.Bundle
import android.os.Message
import android.text.TextUtils
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import android.view.animation.Transformation
import android.widget.TextView
import com.geek.novel.R
import com.geek.novel.activity.base.BaseActivity
import com.geek.novel.bo.AppContext
import com.geek.novel.common.Constant
import com.geek.novel.entity.BookIndex
import com.geek.novel.entity.BookRead
import com.geek.novel.entity.BookSection
import com.geek.novel.services.BookRepository
import com.geek.novel.services.CrawlerRepository
import com.geek.novel.utils.*
import com.geek.novel.view.loading.LoadingDialogUtil
import com.geek.novel.vo.CrawlerSectionVo
import skin.support.content.res.SkinCompatResources
import skin.support.widget.SkinCompatHelper
import skin.support.widget.SkinCompatSupportable
import java.io.File
import java.util.*
import kotlin.collections.ArrayList
import kotlin.math.abs
import kotlin.math.max


@SuppressLint("AppCompatCustomView")
class ReadView : TextView, SkinCompatSupportable {
	
	private var pageLoaded = false
	private var dataLoaded = false
	
	/**全屏点击翻页*/
	private var isFullScreenNextPage = false

	private var bookService = BookRepository.getInstance()
	
	private var crawlerRepository = CrawlerRepository.getInstance()
	
	/**书籍对象*/
	lateinit var book: BookRead
	
	/**书名*/
	lateinit var bookName: String
	
	/**书籍列表*/
	var bookIndexList: List<BookIndex> = ArrayList()
	
	var viewWidth: Int = 0
	var viewHeight: Int = 0

	/**字体文本的颜色*/
	var sectionTextColor: Int = 0

	/**电池控件的颜色*/
	var batteryViewColor: Int = 0
	/**电池控件的边框颜色*/
	var batteryBorderColor: Int = 0

	//缓存三章
	private var section: BookSection? = null
	private var prevSection: BookSection? = null
	private var nextSection: BookSection? = null
	
	private var pages: ArrayList<String> = ArrayList()
	private var prevPages: ArrayList<String> = ArrayList()
	private var nextPages: ArrayList<String> = ArrayList()
	
	var titles: ArrayList<String> = ArrayList()
	private var prevTitles: ArrayList<String> = ArrayList()
	private var nextTitles: ArrayList<String> = ArrayList()

	//电池控件
	private lateinit var batteryView: BatteryView
	
	//初始化的时候赋值
	var titleTextSize = 0f
	var titleTextLineSpace = CommUtil.dip2px(5f)
	var titleTextPaddingTop = CommUtil.dip2px(15f)
	var titleTextPaddingBottom = CommUtil.dip2px(10f)
	var pagesTextSize = 0f
	var contentTextSize = 0f
	var contentLineHeight = 0f
	var contentPaddingTop = 0f
	var contentPaddingBottom = 0f
	
	//计算章节段落时的左右上下间距,用在SectionUtil计算文本内容
	var offsetLR = 0f
	var offsetTB = 0f

	/**动画是否结束*/
	var isAnimationEnd = true

	constructor(context: Context): super(context){
		init(context)
	}
	constructor(context: Context, attrs: AttributeSet): super(context, attrs){
		init(context, attrs)
	}
	constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr){
		init(context, attrs, defStyleAttr)
	}


	//初始化控件
	private fun init(context: Context, attrs: AttributeSet?=null, defStyleAttr: Int=0){

		//初始化属性
		this.initAttrs(attrs, defStyleAttr)

		//换肤处理
		this.applyTopBarBackgroundColor()

		//设置字体类型
		this.setPaintTypeface()
		
		//加载系统配置
		this.loadConfig()

		//自动翻页计时
		this.autoTurnPageTime = this.getAutoTurnPageTime()
		this.resetAutoTurnTime()
		
		//分页文本大小
		pagesTextSize = resources.getDimension(R.dimen.s_12)
		
		//标题顶部边距
		this.contentPaddingTop = resources.getDimension(R.dimen.d_10)
		
		val bottomH = resources.getDimension(R.dimen.read_view_bottom_height)
		this.contentPaddingBottom = resources.getDimension(R.dimen.d_5) + bottomH
		
		//计算章节时候的左右上下间距
		this.offsetLR = paddingLeft + paddingRight + 0f
		this.offsetTB = paddingTop + paddingBottom + contentPaddingTop + contentPaddingBottom
		
		paint.textSize = this.contentTextSize

		//电池，显示电量
		batteryView = BatteryView(context)
		batteryView.vWidth = resources.getDimension(R.dimen.d_20)
		batteryView.vHeight = resources.getDimension(R.dimen.d_10)
		batteryView.setBatteryChangeListener(object: BatteryView.BatteryChangeListener{
			override fun change(level: Int, scale: Int, number: Float) {
				postInvalidate()
			}
		})

	}

	var color: Int = 0
	
	/**加载系统配置*/
	private fun loadConfig(){
		//最大最小的字体大小
		Constant.minTextSize = resources.getDimension(R.dimen.s_10)
		Constant.maxTextSize = resources.getDimension(R.dimen.s_30)
		//最大最小的字体行间距大小
		Constant.minTextLineSize = resources.getDimension(R.dimen.d_5)
		Constant.maxTextLineSize = resources.getDimension(R.dimen.d_20)

		//字体大小
		val textSize = SPUtil[SPUtil.book_text_size, resources.getDimension(R.dimen.s_18), SPUtil.SP_SYSTEM_SETUP] as Float
		this.contentLineHeight = SPUtil[SPUtil.book_line_height, resources.getDimension(R.dimen.d_12), SPUtil.SP_SYSTEM_SETUP] as Float
		
		//设置内容的字体大小
		this.calcContentTextSize(textSize)

		//获取全屏点击翻页设置
		this.isFullScreenNextPage = this.getFullScreenNextPage()
	}



	/**倒计时的定时任务*/
	private var autoTurnPageTimer: Timer? = null

	/**定时任务*/
	private var autoTurnPageTime = 0
	/**定时任务*/
	private var curAutoTurnPageTime = 0

	/**重置倒计时*/
	private fun resetAutoTurnTime(){
		this.curAutoTurnPageTime = this.autoTurnPageTime
	}

	/**倒计时*/
	private fun countdownTimer(){
		if(this.curAutoTurnPageTime <= 1){
			//触发翻页
			this.nextPage()
			//重置倒计时
			this.resetAutoTurnTime()
		}
		this.curAutoTurnPageTime--
		postInvalidate()
	}

	/**定时任务，用户处理定时翻页功能*/
	private fun startAutoTurnPageTimerTask(){
		if(this.getAutoTurnPage()){
			if(autoTurnPageTimer == null){
				this.resetAutoTurnTime()
				postInvalidate()
				autoTurnPageTimer = Timer()
				autoTurnPageTimer!!.schedule(object: TimerTask(){
					override fun run() {
						AppContext.getContext().doOnMainThread{
							//执行倒计时功能
							countdownTimer()
						}
					}
				}, 1000, 1000)
			}
		}else{
			this.stopAutoTurnPageTimerTask()
		}
	}

	/**停止自动翻页的定时任务*/
	fun stopAutoTurnPageTimerTask(){
		if(autoTurnPageTimer != null){
			autoTurnPageTimer!!.cancel()
			autoTurnPageTimer = null
		}
	}

	
	private var offsetX = 0F	//偏移量
	private var startX = 0f		//开始位置
	private var curStartX = 0f	//记录每次拖到的位置，用来判断那一瞬间是向左还是向右滑动
	//记录坐标，为了回滚页面准备的
	private var minStartX = 0f	//记录每次拖到最左边的位置
	private var maxStartX = 0f	//记录每次拖到最右边的位置
	private var isLeft = false

	/**误触的限制，动了该限制以内的，则认为是相同的手势。比如手指按下抬起，只动了一点点，也算作一次点击*/
	private val offsetXLimit = CommUtil.dip2px(20F)

	//private var startY = 0f
	@SuppressLint("ClickableViewAccessibility")
	override fun onTouchEvent(event: MotionEvent?): Boolean {
		if(!isAnimationEnd){
			return true
		}
		when (event!!.action) {
			MotionEvent.ACTION_DOWN -> {
				startX = event.x
				curStartX = event.x
				minStartX = curStartX
				maxStartX = curStartX
				//startY = event.y
			}
			MotionEvent.ACTION_MOVE -> {
				isLeft = curStartX < event.x
				curStartX = event.x
				offsetX = event.x - startX

				minStartX = minStartX.coerceAtMost(curStartX)
				maxStartX = max(maxStartX, curStartX)

				/**当前页面下标*/
				val curPageIndex = this.book.curSectionPage
				if(offsetX < 0){//下一页
					if(curPageIndex == this.pages.size - 1){
						if(this.nextSection == null){
							offsetX = 0f
							return true
						}
					}
				}else if(offsetX > 0){//上一页
					if(curPageIndex == 0){
						if(this.prevSection == null){
							offsetX = 0f
							return true
						}
					}
				}
				
			}
			MotionEvent.ACTION_UP -> {
				val curX = event.x
				if(abs(startX - curX) < offsetXLimit){//没有移动的情况
					offsetX = 0F//重置位置
					//中间的一块位置点击是底部菜单，屏幕中间占三分之一的位置
					val offset = width / 3
					if (startX < width / 2 - offset/2) {
						//如果开启了全屏点击翻页，这里掉下一页
						if(isFullScreenNextPage){
							nextPage()
						}else{
							prevPage()
						}
					} else if (startX > width / 2 + offset/2) {
						nextPage()
					}else{
						//点击了中间，弹出下方的菜单
						this.sendMessage(Constant.handler_event_show_bottom_dialog)
					}
				}else{
					//判断是向左向右还是重置
					if(offsetX == 0F){//拖不动的情况，应该是没有上下页了
						val curReadIndex = this.book.curReadIndex
						if(isLeft){
							if(curReadIndex <= 0){
								ToastUtils.toast(context.getString(R.string.prompt_prev_section_fail))
							}else{
								ToastUtils.toast(context.getString(R.string.prompt_prev_section_loading))
							}
						}else{
							if(curReadIndex >= bookIndexList.size){
								ToastUtils.toast(context.getString(R.string.prompt_next_section_fail))
							}else{
								this.handleLoadingNextSection()
							}
						}
					}else if(curX < startX){//向左滑动
						//判断最小的X和curX比较，如果出现最小的比当前的x还小，说明之前滑动回来了
						if(minStartX < curX && abs(minStartX - curX)>offsetXLimit){
							moveToPosition(offsetX, 0F, ActionEvent.ActionReset)
						}else{
							moveToPosition(offsetX, -width.toFloat(), ActionEvent.ActionRight)
						}
					}else{//向右滑动
						//判断最大的X和curX比较，如果出现最大的比当前的x还大，说明之前滑动回来了
						if(curX < maxStartX && abs(maxStartX - curX)>offsetXLimit){
							moveToPosition(offsetX, 0F, ActionEvent.ActionReset)
						}else{
							moveToPosition(offsetX, width.toFloat(), ActionEvent.ActionLeft)
						}
					}
				}
			}
		}
		postInvalidate()
		return true
	}


	/**处理正在加载下一章节的提示*/
	private fun handleLoadingNextSection(){
		this.isUserWaitLoadingNext = true
		ToastUtils.toast(context.getString(R.string.prompt_next_section_loading))
	}

	/**高速用户下一章加载完毕了*/
	private fun handleToastNextSectionLoaded(){
		this.isUserWaitLoadingNext = false
		ToastUtils.toast(context.getString(R.string.prompt_next_section_is_loaded))
	}

	
	//移动动画
	private fun moveToPosition(mStart: Float, mEnd: Float, action: ActionEvent){
		val anim = SlideAnimation(mStart, mEnd, action)
		anim.setAnimationListener(mOpenListener)
		startAnimation(anim)
	}

	private var currentTypeface = Typeface.DEFAULT
	/**设置字体*/
	fun setPaintTypeface(){
		//设置默认字体
		currentTypeface = Typeface.DEFAULT
		//获取当前使用的字体文件
		val curSelectTypeface = SPUtil[SPUtil.book_typeface, "", SPUtil.SP_SYSTEM_SETUP] as String
		if(!TextUtils.isEmpty(curSelectTypeface)){
			val file = File(Constant.TypefacePath, curSelectTypeface)
			if(file.exists()){
				try {
					val typeface = Typeface.createFromFile(file)
					//设置字体类型
					currentTypeface = typeface
				} catch (e: Exception) {
					ToastUtils.toast("字体文件引用失败，请重新下载：${e.message}")
				}
			}
		}

	}
	
	override fun onDraw(canvas: Canvas) {
		//设置画笔颜色
		paint.color = sectionTextColor

		if(section == null){
			return
		}
		
		//绘制三页
		val index = book.curSectionPage
		
		var prevT = titles
		var prevP = pages
		var prevS = section
		var prevIndex = index-1
		if(prevIndex < 0){
			prevS = prevSection
			prevT = prevTitles
			prevP = prevPages
			prevIndex = prevPages.size-1
		}
		
		var nextT = titles
		var nextP = pages
		var nextS = section
		var nextIndex = index+1
		if(nextIndex >= pages.size){
			nextS = nextSection
			nextT = nextTitles
			nextP = nextPages
			nextIndex = 0
		}

		if(offsetX > 0){
			drawPage(canvas, prevS, prevT, prevP, prevIndex, offsetX - width)
		}
		drawPage(canvas, section, titles, pages, index, offsetX)
		if(offsetX < 0){
			drawPage(canvas, nextS, nextT, nextP, nextIndex, offsetX + width)
		}

	}
	
	/**绘制章节内容*/
	private fun drawPage(canvas: Canvas, bookSection: BookSection?, titles: ArrayList<String>, pages: ArrayList<String>, index: Int, posX: Float){
		if(bookSection == null){
			return
		}
		//设置字体
		paint.typeface = currentTypeface
		
		//计算页码
		var indexVal = index
		if(pages.size <= indexVal || indexVal < 0) {
			indexVal = 0
		}
		
		//左边距
		val left = posX + paddingLeft + contentTextSize/4
		
		canvas.save()

		//只有第一页才需要显示章节名
		var titleBaseLineY = 0F
		if(indexVal == 0){
			//绘制章节名
			paint.textSize = titleTextSize
			titleBaseLineY += titleTextPaddingTop
			for (title in titles) {
				titleBaseLineY += titleTextSize + titleTextLineSpace
				canvas.drawText(title, 0, title.length, left, titleBaseLineY, paint)
			}
			titleBaseLineY += titleTextPaddingBottom
		}

		if(pages.isNotEmpty()){
			//绘制内容
			paint.textSize = contentTextSize
			val page = pages[indexVal]
			val lines = page.split("\n")

			//再添加一点偏移量
			val contentOffsetTop = 0F//CommUtil.dip2px(5f)

			val lineHeight = contentTextSize + contentLineHeight
			var textY: Float
			try {
				val fontMetrics = paint.fontMetrics
				//这里是top因为基于baseline向上计算的，是负数。负负得正。这样才能让字体顶部对齐
				val textLineHeight = -fontMetrics.top
				val contentBaseLineY = 0 + contentPaddingTop + textLineHeight + contentOffsetTop + titleBaseLineY

				for ((i, line) in lines.withIndex()){
					//Android的drawText是根据基准线绘制的，所以还需要计算位置
					textY = lineHeight * i + contentBaseLineY
					canvas.drawText(line, 0, line.length, left, textY, paint)
				}
			}catch (e: Exception){
				LogCatUtil.e("ReadView-onDraw", "${e.message}", e)
			}
		}

		canvas.restore()
		
		//绘制电池
		drawBattery(canvas, left)
		
		// 绘制章节的页码
		drawPageIndex(canvas, left, pages, indexVal)

		drawAutoTurnPage(canvas, left)
	}

	/**绘制电池*/
	private fun drawBattery(canvas: Canvas, offsetX: Float){
		val left = offsetX
		val offset = resources.getDimension(R.dimen.read_view_bottom_height)
		val top = height.toFloat() - offset
		batteryView.setViewColor(batteryViewColor, batteryBorderColor)
		batteryView.drawView(canvas, left, top)
	}

	/**绘制自动翻页提示*/
	private fun drawAutoTurnPage(canvas: Canvas, offsetX: Float){
		if(this.autoTurnPageTimer == null){
			return
		}
		canvas.save()
		paint.textSize = pagesTextSize
		paint.typeface = Typeface.DEFAULT

		val text = "自动翻页：${curAutoTurnPageTime}..."
		val left = offsetX + width/2 - paint.measureText(text)/2
		val top = height.toFloat() - resources.getDimension(R.dimen.d_8)
		canvas.drawText(text, 0, text.length, left, top, paint)
		canvas.restore()
	}
	
	/**绘制章节的页码*/
	private fun drawPageIndex(canvas: Canvas, offsetX: Float, pages: ArrayList<String>, indexVal: Int){
		canvas.save()
		paint.textSize = pagesTextSize
		paint.typeface = Typeface.DEFAULT
		
		val text = "${indexVal+1}/${pages.size}页"
		val left = offsetX + width - paint.measureText(text) - offsetLR
//		val offset = resources.getDimension(R.dimen.read_view_bottom_height)
		val top = height.toFloat() - resources.getDimension(R.dimen.d_8)
		canvas.drawText(text, 0, text.length, left, top, paint)
		canvas.restore()
	}
	
	/**
	 * 字体加大
	 */
	fun textSizeAdd(): Float {
		val size = this.contentTextSize + Constant.stepTextSize
		this.initContentTextSize(size)
		return size
	}
	/**
	 * 字体减小
	 */
	fun textSizeMinus(): Float {
		val size = this.contentTextSize - Constant.stepTextSize
		this.initContentTextSize(size)
		return size
	}


	/**
	 * 字体行间距加大
	 */
	fun textLineSizeAdd(): Float {
		val size = this.contentLineHeight + Constant.stepTextLineSize
		this.initContentTextSize(null, size)
		return size
	}
	/**
	 * 字体行间距减小
	 */
	fun textLineSizeMinus(): Float {
		val size = this.contentLineHeight - Constant.stepTextLineSize
		this.initContentTextSize(null, size)
		return size
	}

	/**
	 * 设置字体大小
	 */
	private fun initContentTextSize(size: Float?, lineHeight: Float?=null) {
		//设置字体大小
		if(size != null){
			this.calcContentTextSize(size)
			//保存到系统设置中
			SPUtil.put(SPUtil.book_text_size, this.contentTextSize, SPUtil.SP_SYSTEM_SETUP)
			this.paint.textSize = this.contentTextSize
		}

		//设置行间距
		if(lineHeight != null){
			this.contentLineHeight = when {
				lineHeight < Constant.minTextLineSize -> Constant.minTextLineSize
				lineHeight > Constant.maxTextLineSize -> Constant.maxTextLineSize
				else -> lineHeight
			}
			//保存到系统设置中
			SPUtil.put(SPUtil.book_line_height, this.contentLineHeight, SPUtil.SP_SYSTEM_SETUP)
		}

		//重新计算章节对象
		this.updateAllSection()
		
		var curPage = this.book.curSectionPage
		if(curPage >= pages.size){
			curPage = pages.size-1
			this.book.curSectionPage = curPage
			bookService.save(book)
		}
		
		//重新绘制页面
		postInvalidate()
		
	}
	
	/**
	 * 计算内容字体大小
	 */
	private fun calcContentTextSize(size: Float){
		this.contentTextSize = when {
			size < Constant.minTextSize -> Constant.minTextSize
			size > Constant.maxTextSize -> Constant.maxTextSize
			else -> size
		}
		//标题大小，暂定为根据字体进行计算
		this.titleTextSize = this.contentTextSize * 3/2
	}

	/**获取全屏点击翻页设置*/
	fun getFullScreenNextPage(): Boolean{
		return SPUtil[SPUtil.book_pull_page_next, false, SPUtil.SP_SYSTEM_SETUP] as Boolean
	}
	
	/**设置全屏点击翻页*/
	fun setFullScreenNextPage(bool: Boolean){
		this.isFullScreenNextPage = bool
		SPUtil.put(SPUtil.book_pull_page_next, bool, SPUtil.SP_SYSTEM_SETUP)
	}

	/**获取自动翻页*/
	fun getAutoTurnPage(): Boolean{
		return SPUtil[SPUtil.book_auto_turn_page, false, SPUtil.SP_SYSTEM_SETUP] as Boolean
	}
	/**设置自动翻页*/
	fun setAutoTurnPage(bool: Boolean){
		SPUtil.put(SPUtil.book_auto_turn_page, bool, SPUtil.SP_SYSTEM_SETUP)
	}

	/**获取自动翻页时长*/
	fun getAutoTurnPageTime(): Int{
		return SPUtil[SPUtil.book_auto_turn_page_time, 20, SPUtil.SP_SYSTEM_SETUP] as Int
	}
	/**设置自动翻页时长-1*/
	fun autoTurnPageTimeMinus(){
		this.setAutoTurnPageTime(this.autoTurnPageTime-1)
	}
	/**设置自动翻页时长+1*/
	fun autoTurnPageTimeAdd(){
		this.setAutoTurnPageTime(this.autoTurnPageTime+1)
	}
	/**设置自动翻页时长*/
	private fun setAutoTurnPageTime(time: Int){
		val result = if(time < Constant.minAutoTurnPageTime){
			Constant.minAutoTurnPageTime
		}else if(time > Constant.maxAutoTurnPageTime){
			Constant.maxAutoTurnPageTime
		}else{
			time
		}
		this.autoTurnPageTime = result
		SPUtil.put(SPUtil.book_auto_turn_page_time, result, SPUtil.SP_SYSTEM_SETUP)
		//重置时间
		this.resetAutoTurnTime()
	}


	/**
	 * 绘制上下一页的时候，需要重新计算三个章节
	 * 上一页
	 */
	fun prevPage(){
		this.resetAutoTurnTime()
		if(this.book.curSectionPage == 0){
			if(this.book.curReadIndex <= 0){
				ToastUtils.toast(context.getString(R.string.prompt_prev_section_fail))
				return
			}
			this.showPrevSection()
			this.book.curSectionPage = this.pages.size-1
			bookService.save(book)
			postInvalidate()
		}else{
			this.book.curSectionPage--
			bookService.save(book)
			postInvalidate()
		}
	}
	
	/**
	 * 绘制上下一页的时候，需要重新计算三个页面
	 * 下一页
	 */
	fun nextPage(){
		this.resetAutoTurnTime()
		if (this.book.curSectionPage >= this.pages.size - 1) {
			if(this.book.curReadIndex >= bookIndexList.size-1){
				ToastUtils.toast(context.getString(R.string.prompt_next_section_fail))
				return
			}
			this.showNextSection()
		} else {
			this.book.curSectionPage++
			bookService.save(book)
			postInvalidate()
		}
	}
	
	/**
	 * 判断是否正在请求加载中
	 */
	private var isSectionLoadingPrev = false

	/**
	 * 判断是否正在请求加载中
	 */
	private var isSectionLoadingNext = false

	/**用户是否正在等待加载下一章*/
	private var isUserWaitLoadingNext = false

	/**
	 * 上一章节
	 */
	fun showPrevSection(){
		this.resetAutoTurnTime()
		if(isSectionLoadingPrev){
			ToastUtils.toast(context.getString(R.string.prompt_prev_section_loading))
			return
		}
		val curReadIndex = this.book.curReadIndex -1
		if(this.prevSection == null){
			if(curReadIndex <= 0){
				ToastUtils.toast(context.getString(R.string.prompt_prev_section_fail))
				return
			}
		}
		this.nextSection = this.section
		this.section = this.prevSection
		this.nextTitles = this.titles
		this.nextPages = this.pages
		this.titles = this.prevTitles
		this.pages = this.prevPages
		
		this.book.curReadIndex--
		this.book.curSectionPage = 0
		bookService.save(book)
		postInvalidate()
		
		//发起获取上一章的请求
		this.queryPrevSection()
	}
	

	/**
	 * 下一章节
	 */
	fun showNextSection(){
		this.resetAutoTurnTime()
		//正在加载中，弹提示
		if(isSectionLoadingNext){
			this.handleLoadingNextSection()
			return
		}
		if(this.nextSection == null){
			ToastUtils.toast(context.getString(R.string.prompt_next_section_fail))
			return
		}
		this.prevSection = this.section
		this.section = this.nextSection
		this.prevTitles = this.titles
		this.prevPages = this.pages
		this.titles = this.nextTitles
		this.pages = this.nextPages
		
		this.book.curReadIndex++
		this.book.curSectionPage = 0
		bookService.save(book)

		//发起获取下一章的请求
		this.queryNextSection()
		
		postInvalidate()
	}
	
	/**每次加载两个章节*/
	private fun initBookSection(){
		if(this.section == null){
			//获取当前阅读章节
			val index = this.book.curReadIndex
			val bookIndex = this.getBookIndex(index)
			this.loadBookSection(index, bookIndex, false)
		}
	}

	/**加载章节信息*/
	fun loadBookSection(index: Int, bookIndex: BookIndex?, resetCurPage: Boolean = true){
		this.stopAutoTurnPageTimerTask()
		if(bookIndex != null){
			bookIndex.indexNum = index
			this.book.curReadIndex = index
			if(resetCurPage){
				this.book.curSectionPage = 0
			}
			bookService.save(book)

			crawlerRepository.startCrawlerBookSectionAsync(book, bookIndex, this.getBaseActivity(), true)
		}
	}

	/**重新计算章节内容*/
	private fun updateAllSection(){
		titles = this.loadTitles(this.section)
		pages = this.loadPages(this.section)
		prevTitles = this.loadTitles(this.prevSection)
		prevPages = this.loadPages(this.prevSection)
		nextTitles = this.loadTitles(this.nextSection)
		nextPages = this.loadPages(this.nextSection)
	}
	
	/**更新章节信息*/
	private fun updateCurrentSection(section: BookSection){
		//关闭loading页面
		LoadingDialogUtil.getInstance().dismiss()
		//加载章节数据
		this.section = section
		this.titles = this.loadTitles(section)
		this.pages = this.loadPages(section)
		
		//重新绘制页面
		postInvalidate()
		
		//发起加载下一章的请求
		this.queryNextSection()
		//发起加载上一章的请求
		this.queryPrevSection()

		//重置自动翻页的定时器
		this.stopAutoTurnPageTimerTask()
		this.startAutoTurnPageTimerTask()
	}


	private fun updatePrevSection(section: BookSection){
		//加载章节数据
		this.prevSection = section
		this.prevTitles = this.loadTitles(section)
		this.prevPages = this.loadPages(section)

		LogCatUtil.i("???", "更新上一章节：${book.curReadIndex}")

		this.isSectionLoadingPrev = false
	}


	private fun updateNextSection(section: BookSection){
		//加载章节数据
		this.nextSection = section
		this.nextTitles = this.loadTitles(section)
		this.nextPages = this.loadPages(section)

		this.isSectionLoadingNext = false

		//提示用户下一章已经加载完毕了
		if(this.isUserWaitLoadingNext){
			this.handleToastNextSectionLoaded()
		}
	}
	
	/**
	 * 从网络数据加载上一章信息
	 */
	private fun queryPrevSection(){
		this.prevSection = null
		//这里这么先置为true，是因为存在缓存的情况下，变量是没有异步执行，直接就返回结果了
		this.isSectionLoadingPrev = true
		val result = this.querySection(this.book.curReadIndex -1)
		if(!result){
			this.isSectionLoadingPrev = false
		}
	}
	
	/**
	 * 从网络数据加载下一章信息
	 */
	private fun queryNextSection(){
		this.nextSection = null
		//这里这么先置为true，是因为存在缓存的情况下，变量是没有异步执行，直接就返回结果了
		this.isSectionLoadingNext = true
		val result = this.querySection(this.book.curReadIndex + 1)
		if(!result){
			this.isSectionLoadingNext = false
		}
	}


	/**发起请求缓存章节信息*/
	private fun querySection(curReadIndex: Int): Boolean{
		if(curReadIndex < 0 || curReadIndex >= bookIndexList.size){
			return false
		}
		val bookIndex = this.getBookIndex(curReadIndex)
		if(bookIndex != null){
			crawlerRepository.startCrawlerBookSectionAsync(book, bookIndex, this.getBaseActivity())
			return true
		}
		return false
	}


	/**
	 * 根据下标获取章节索引
	 */
	private fun getBookIndex(index: Int): BookIndex?{
		val list = this.bookIndexList
		if(list.isEmpty()){
			throw RuntimeException("获取章节列表为空! 在activity就该提示弹出获取爬虫源了")
		}
		if(index < 0 || index >= list.size){
			return null
		}
		val bookIndex = list[index]
		bookIndex.indexNum = index
		return bookIndex
	}
	
	/**将章节标题加载成titles数组*/
	private fun loadTitles(section: BookSection?): ArrayList<String>{
		return if(section == null){
			ArrayList()
		}else{
			val title = section.title
			SectionUtil.divideTitle(title, this)
		}
	}
	
	/**将章节加载成pages数组*/
	private fun loadPages(section: BookSection?): ArrayList<String>{
		return if(section == null){
			ArrayList()
		}else{
			paint.typeface = currentTypeface
			
			val title = section.title
			val result = crawlerRepository.formatBookSectionContent(book, section.content!!)
			SectionUtil.divideSection(title, result, this)
		}
	}
	
	/**初始化书本数据*/
	fun initBook(book: BookRead, bookIndexList: List<BookIndex>) {
		try {
			this.book = book
			this.bookIndexList = bookIndexList
			this.dataLoaded = true
			
			this.section = null
			this.prevSection = null
			this.nextSection = null
			
			//页面加载完成之后再加载章节内容，否则只能等待
			if(this.pageLoaded){
				this.initBookSection()
			}
		}catch (e: Exception){
			ToastUtils.toast("${e.message}")
		}
	}

	//测量页面的时候加载数据
	override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec)
		
		val width = MeasureSpec.getSize(widthMeasureSpec)
		val height = MeasureSpec.getSize(heightMeasureSpec)
		
		//加载完毕了，而且有数据，这时候发生改变，那就重新更新数据
		if(this.pageLoaded && (viewWidth!=width || viewHeight!=height) && this.section != null){
			LogCatUtil.d("???", "测量, 宽度：$viewWidth -> $width, 高度：$viewHeight -> $height")
			viewWidth = width
			viewHeight = height
			this.updateAllSection()
		}else{
			viewWidth = width
			viewHeight = height
		}
		
		if(!this.pageLoaded && this.dataLoaded){
			this.initBookSection()
		}
		this.pageLoaded = true
	}

	/**动画的监听器*/
	private val mOpenListener = object : Animation.AnimationListener {

		override fun onAnimationStart(animation: Animation) {
			isAnimationEnd = false
		}

		override fun onAnimationRepeat(animation: Animation) {
		}

		override fun onAnimationEnd(animation: Animation) {
			val anim = animation as SlideAnimation
			isAnimationEnd = true

			//动画结束,重置位置
			offsetX = 0f
			when (anim.action) {
				ActionEvent.ActionLeft -> {
					prevPage()
				}
				ActionEvent.ActionRight -> {
					nextPage()
				}
				ActionEvent.ActionReset -> {
				}
			}
		}
	}

	/**
	 * 设置动画
	 */
	private inner class SlideAnimation(private val mStart: Float, private val mEnd: Float, val action: ActionEvent) : Animation() {
		init {
			val speed = 2.5f
			interpolator = DecelerateInterpolator()
			val duration = abs(mEnd - mStart) / speed
			setDuration(duration.toLong())
		}
		
		override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
			super.applyTransformation(interpolatedTime, t)
			if(!isAnimationEnd){
				val offset = (mEnd - mStart) * interpolatedTime + mStart
				offsetX = offset
				postInvalidate()
			}
			
		}
		
	}
	
	/**
	 * 动画的位置的枚举值
	 **/
	private enum class ActionEvent{
		ActionLeft, ActionRight, ActionReset,
	}


	/**控件背景的资源id*/
	private var viewTextColorResId: Int? = null
	private var batteryViewColorResId: Int? = null
	private var batteryBorderColorResId: Int? = null

	/**初始化属性*/
	private fun initAttrs(attrs: AttributeSet?, defStyleAttr: Int=0) {
		//获取属性
		val array = context.obtainStyledAttributes(attrs, R.styleable.ReadView, defStyleAttr, 0)
		viewTextColorResId = array.getResourceId(R.styleable.ReadView_textColor, SkinCompatHelper.INVALID_ID)
		batteryViewColorResId = array.getResourceId(R.styleable.ReadView_batteryViewColor, SkinCompatHelper.INVALID_ID)
		batteryBorderColorResId = array.getResourceId(R.styleable.ReadView_batteryBorderColor, SkinCompatHelper.INVALID_ID)
		array.recycle()
	}

	//换肤处理
	private fun applyTopBarBackgroundColor() {
		viewTextColorResId = SkinCompatHelper.checkResourceId(viewTextColorResId!!)
		batteryViewColorResId = SkinCompatHelper.checkResourceId(batteryViewColorResId!!)
		batteryBorderColorResId = SkinCompatHelper.checkResourceId(batteryBorderColorResId!!)
		if (viewTextColorResId != SkinCompatHelper.INVALID_ID) {
			sectionTextColor = SkinCompatResources.getColor(context, viewTextColorResId!!)
			batteryViewColor = SkinCompatResources.getColor(context, batteryViewColorResId!!)
			batteryBorderColor = SkinCompatResources.getColor(context, batteryBorderColorResId!!)
			postInvalidate()
		}
	}

	override fun applySkin() {
		//应用运行间，手动切换换肤回调，再次进行换肤操作
		applyTopBarBackgroundColor()
	}

	/**销毁*/
	fun onDestroy(){
		//销毁时调用电池的注销方法
		batteryView.onDestroy()

		//关闭定时器
		this.stopAutoTurnPageTimerTask()
	}

	fun onShow(){
		//重置倒计时
		this.startAutoTurnPageTimerTask()
	}

	fun onHide(){
		this.stopAutoTurnPageTimerTask()
	}
	
	private fun getBaseActivity(): BaseActivity{
		return context as BaseActivity
	}
	
	/**
	 * 发送事件
	 */
	private fun sendMessage(code: Int, obj: Any?=null, data: Bundle?=null){
		this.getBaseActivity().sendHandlerMessage(code, obj, data)
	}
	
	
	fun handleMessage(msg: Message){
		when(msg.what){
			//发起请求加载章节数据
			Constant.handler_event_load_book_section->{
				//关闭loading弹窗
				LoadingDialogUtil.getInstance().dismiss()

				//回传章节的对象，根据下标判断是是否加载上下章节
				val crawlerSectionVo = msg.obj as CrawlerSectionVo
				if(crawlerSectionVo.code == Constant.RESPONSE_CODE_SUCCESS){
					val bookSection = crawlerSectionVo.section!!

					val curSectionIndex = crawlerSectionVo.curSectionIndex!!
					val curReadIndex = book.curReadIndex
					LogCatUtil.i("???", "书籍index：${curReadIndex}, 加载的index：${curSectionIndex}")
					when (curSectionIndex) {
						curReadIndex -> {
							this.updateCurrentSection(bookSection)
						}
						curReadIndex-1 -> {
							this.updatePrevSection(bookSection)
						}
						curReadIndex+1 -> {
							this.updateNextSection(bookSection)
						}
					}

					//将加载上一章的标志位清空，避免无法加载数据的问题
					if(curSectionIndex < curReadIndex){
						this.isSectionLoadingPrev = false
					}
					//将加载下一章的标志位清空，避免无法加载数据的问题
					if(curSectionIndex > curReadIndex){
						this.isSectionLoadingNext = false
					}
				}
			}
		}
	}
	
}